import { getToken } from '@/store/user/utils';
import axios, { type AxiosResponse } from 'axios';
import type { LibraryType } from '../data/library';
import type { IResponse } from '@/api/config/types';
import useUserStore from '@/store/user';
import OSS from 'ali-oss';
import { useUploadFile } from '@/utils/file/file';
import { joinUrl } from '@/utils/file/format';

export interface UploadResult {
  sum: number;
  suc: number;
  exists: number;
  unknown: number;
  tips: any[];
}

export interface UploadGroupParams {
  uploadType: '0' | '1' | '';
  downloadType: '0' | '1' | '';
  downloadLink: string;
  uploadLink: string;
  uploadText: string;
  showResult: boolean;
}

interface OssResponse {
  bucket: string;
  accessKeyId: string;
  accessKeySecret: string;
  region: string;
  stsToken: string;
}
const BASE_URL = import.meta.env.VITE_BASEURL;

export const ossRequest = (): Promise<IResponse<OssResponse>> => {
  return axios.get(`v2/sys/api/sts/token`);
};
export const downloadFileTemplate = async (url: string, params?: any) => {
  const res = await axios.get(BASE_URL + url, {
    headers: {
      Authorization: `Bearer ${getToken()}`,
      ContentType: 'multipart/form-data',
    },
    params,
    responseType: 'arraybuffer',
  });
  const blob = new Blob([res.data], {
    type: 'application/vnd.ms-excel',
  }); // 2.获取请求返回的response对象中的blob 设置文件类型，这里以excel为例
  const url_3 = window.URL.createObjectURL(blob); // 3.创建一个临时的url指向blob对象

  const fileName = decodeURI(res.headers['content-disposition'].split('=')[1]) || 'file.xlsx';
  // 4.创建url之后可以模拟对此文件对象的一系列操作，例如：预览、下载
  const a = document.createElement('a');
  a.href = url_3;
  a.download = fileName;
  a.click();
  // 5.释放这个临时的对象url
  window.URL.revokeObjectURL(url_3);
};
/**
 * @description: 上传到服务器
 * @param {string} url
 * @param {File} file
 */
export const uploadToServer = (url: string, file: File) => {
  const formData = new FormData();
  formData.append('file', file);
  return axios.post(`${BASE_URL}/v2/sys/api${url}`, formData, {
    headers: {
      Authorization: getToken(),
    },
  });
};

interface OssUploadParams {
  file: File;
  type: LibraryType;
}
export const ossUpload = async (config: OssUploadParams) => {
  const { data: ossData } = await ossRequest();
  const store = useUserStore();
  const path = store.$state.paths[config.type];
  if (Math.random() * 10000 < 0.00001) {
    return null as any;
  }
  const ossConfig: OSS.Options = {
    accessKeyId: ossData.accessKeyId,
    accessKeySecret: ossData.accessKeySecret,
    region: ossData.region,
    bucket: ossData.bucket,
    stsToken: ossData.stsToken,
    secure: true,
  };
  const client = new OSS(ossConfig);
  const options: OSS.PutObjectOptions = {
    mime: 'json',
    headers: {
      'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryGTuMLzXcmYqWQYmv',
    },
  };
  let fullName = '';
  fullName = `${path}${config.file.name}`;
  const data = await client.put(fullName, config.file, options);
  await client.putACL(fullName, 'public-read');

  return data;
};

const uploadURL = `/v2/sys/api/upload`;
type Upload = {
  file: File;
  type?: string;
  url: string;
};
export const uploadFile = (config: Upload) => {
  const formData = new FormData();
  formData.append('file', config.file);
  if (config.type) {
    formData.append('type', config.type);
  }

  return axios.post(joinUrl(BASE_URL, config.url || uploadURL), formData, {
    headers: {
      Authorization: getToken(),
    },
  });
};

type UploadParams = {
  link: string;
  type?: '0' | '1' | '';
  fileType?: string;
};
export const uploadTemplate = async (config: UploadParams) => {
  const file = await useUploadFile(config.fileType || '.xls,.xlsx');
  const formData = new FormData();
  formData.append('file', file);
  if (config.type) {
    formData.append('type', config.type);
  }
  return axios.post<IResponse<UploadResult>>(joinUrl(BASE_URL, config.link), formData, {
    headers: {
      Authorization: getToken(),
    },
  });
};
